package pr1.cromosoma;

import java.util.Arrays;
import java.util.List;

public class CromosomaF2 extends Cromosoma<List<Double>> {

	private static final double XMAX = 12.1;
	private static final double XMIN = -3;
    private static final double YMAX = 5.8;
	private static final double YMIN = 4.1;

    private final int longX, longY;

    private CromosomaF2(int longX, int longY) {
		super(longX + longY);
        this.longX = longX;
        this.longY = longY;
        setAptitud(evalua());
	}

    @Override
    public CromosomaF2 clone() {
        CromosomaF2 clon = new CromosomaF2(longX, longY);
        clon.copia(this);
        return clon;
    }

    public void copia(CromosomaF2 otro) {
        assert(this.longX == otro.longX && this.longY == otro.longY);
        super.copia(otro);
    }

	@Override
	public final double evalua() {
        double x = getX();
        double y = getY();
        double cnt = 21.5;
        double s1 = x * Math.sin(4 * Math.PI * x);
        double s2 = y * Math.sin(20 * Math.PI * y);
		return cnt + s1 + s2;
	}

	public double getX() {
		return XMIN + (XMAX - XMIN) * bin2dec(0, longX)
				/ (Math.pow(2, longX) - 1);
	}

    public double getY() {
		return YMIN + (YMAX - YMIN) * bin2dec(longX, longY)
				/ (Math.pow(2, longY) - 1);
	}

    @Override
    public List<Double> getFenotipo() {
        return Arrays.asList(new Double[] {getX(), getY()});
    }

	public static class Factory implements CromosomaFactory {

		double precision;
		int longX, longY;

		public double getPrecision() {
			return precision;
		}

		public void setPrecision(double precision) {
			this.precision = precision;
			longX = (int) Math.ceil(Math.log(1 + (XMAX - XMIN)
					/ precision)
					/ Math.log(2));
            longY = (int) Math.ceil(Math.log(1 + (YMAX - YMIN)
					/ precision)
					/ Math.log(2));
		}

		public Cromosoma generaCromosoma() {
			return new CromosomaF2(longX, longY);
		}
		
		public String toString() {
			return "Cromosoma 2";
		}
	}
}
